package com.ukefu.webim.web.handler.admin.users;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.util.task.DSData;
import com.ukefu.util.task.DSDataEvent;
import com.ukefu.util.task.ExcelImportProecess;
import com.ukefu.util.task.process.UserProcess;
import com.ukefu.webim.service.acd.ServiceQuene;
import com.ukefu.webim.service.cache.CacheHelper;
import com.ukefu.webim.service.repository.ExtentionRepository;
import com.ukefu.webim.service.repository.MetadataRepository;
import com.ukefu.webim.service.repository.PbxHostOrgiRelaRepository;
import com.ukefu.webim.service.repository.PbxHostRepository;
import com.ukefu.webim.service.repository.ReporterRepository;
import com.ukefu.webim.service.repository.UserRepository;
import com.ukefu.webim.service.repository.UserRoleRepository;
import com.ukefu.webim.util.OnlineUserUtils;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.model.AgentStatus;
import com.ukefu.webim.web.model.Extention;
import com.ukefu.webim.web.model.MetadataTable;
import com.ukefu.webim.web.model.PbxHost;
import com.ukefu.webim.web.model.PbxHostOrgiRela;
import com.ukefu.webim.web.model.SystemConfig;
import com.ukefu.webim.web.model.User;
import com.ukefu.webim.web.model.UserRole;

/**
 *
 * @author 程序猿DD
 * @version 1.0.0
 * @blog http://blog.didispace.com
 *
 */
@Controller
@RequestMapping("/admin/user")
public class UsersController extends Handler{
	
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private UserRoleRepository userRoleRes;
	
	@Autowired
	private PbxHostRepository pbxHostRes ;
	
	@Autowired
	private ExtentionRepository extentionRes;

	@Autowired
	private PbxHostOrgiRelaRepository pbxHostOrgiRelaRepository ;
	
	@Value("${web.upload-path}")
    private String path;
	
	@Autowired
	private ReporterRepository reporterRes ;
	
	@Autowired
	private MetadataRepository metadataRes ;

    @RequestMapping("/index")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView index(ModelMap map , final HttpServletRequest request) throws FileNotFoundException, IOException {
    	//map.addAttribute("userList", userRepository.findByDatastatusAndOrgiAndOrgid(false, super.getOrgiByTenantshare(request),super.getOrgid(request), new PageRequest(super.getP(request), super.getPs(request), Sort.Direction.ASC, "createtime")));
    	final String orgi = super.getOrgi(request);
    	Page<User> page = userRepository.findAll(new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();  
				Predicate p = cb.and(cb.equal(root.get("orgi").as(String.class), orgi),cb.equal(root.get("datastatus").as(boolean.class), false));
				Predicate p1 = cb.or(cb.like(root.get("username").as(String.class), "%"+request.getParameter("q")+"%")
						,cb.like(root.get("uname").as(String.class), "%"+request.getParameter("q")+"%")
						,cb.like(root.get("email").as(String.class), "%"+request.getParameter("q")+"%")
						,cb.like(root.get("mobile").as(String.class), "%"+request.getParameter("q")+"%")
						);
				list.add(p);
				if(!org.apache.commons.lang3.StringUtils.isBlank(request.getParameter("q"))) {
					list.add(cb.and(p1));
				}
				Predicate[] p2 = new Predicate[list.size()];  
		        query.where(cb.and(list.toArray(p2)));
				return query.getRestriction();  
			}
		}, new PageRequest(super.getP(request), super.getPs(request), Sort.Direction.DESC,new String[] {"createtime"}));
    	map.addAttribute("userList", page);
    	map.addAttribute("q", request.getParameter("q"));
    	map.addAttribute("p", super.getP(request));
    	return request(super.createAdminTempletResponse("/admin/user/index"));
    }
    
    @RequestMapping("/add")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView add(ModelMap map , HttpServletRequest request) {
    	if(UKDataContext.model.get("callcenter") != null) {
    		List<PbxHost> pbxHostList = new ArrayList<>();
			SystemConfig systemConfig = UKTools.getSystemConfig();
			//多租户 要查租户和语音服务器的关联表
			if(systemConfig!=null&&systemConfig.isEnabletneant()) {

				List<String> pbxHostIds = new ArrayList<>();
				List<PbxHostOrgiRela> pbxHostOrgiRelaList = pbxHostOrgiRelaRepository.findByOrgi(super.getOrgi(request)) ;

				if(!pbxHostOrgiRelaList.isEmpty()) {
					for(PbxHostOrgiRela rel:pbxHostOrgiRelaList) {
						pbxHostIds.add(rel.getPbxhostid());
					}
				}
				if(pbxHostIds.size() > 0){
					pbxHostList = pbxHostRes.findByIdIn(pbxHostIds);
				}
			}else{
				pbxHostList = pbxHostRes.findByOrgi(super.getOrgi(request)) ;
			}
			map.addAttribute("pbxHostList",pbxHostList);
    		if(pbxHostList!=null && !pbxHostList.isEmpty()) {
    			PbxHost pbxHost = pbxHostList.get(0) ;
    			map.addAttribute("pbxHost",pbxHost);
    			map.addAttribute("extentionList",extentionRes.findByHostidAndExtypeAndOrgi(pbxHost.getId() , UKDataContext.ExtentionType.LINE.toString(), super.getOrgi(request)));
    		}
    	}
        return request(super.createRequestPageTempletResponse("/admin/user/add"));
    }
    
    @RequestMapping("/save")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView save(HttpServletRequest request ,@Valid User user) {
    	String msg = "" ;
    	user.setId(UKTools.getUUID());
    	msg = validUser(user);
    	if(!StringUtils.isBlank(msg)){
    		return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html?msg="+msg));
    	}else if(!StringUtils.isBlank(user.getUsername()) && !StringUtils.isBlank(user.getPassword())){
    		if(request.getParameter("admin")!=null && super.getUser(request).isSuperuser()){
    			user.setUsertype("0");
    		}else{
    			user.setUsertype(null);
    		}
    		if(!StringUtils.isBlank(user.getPassword())){
    			user.setPassword(UKTools.md5(user.getPassword()));
    		}
    		
    		user.setOrgi(super.getOrgiByTenantshare(request));
    		if(!StringUtils.isBlank(super.getUser(request).getOrgid())) {
    			user.setOrgid(super.getUser(request).getOrgid());
    		}else {
    			user.setOrgid(UKDataContext.SYSTEM_ORGI);
    		}
    		if(!StringUtils.isBlank(user.getExtid())) {
    			List<User> userList = userRepository.findByOrgiAndExtidAndDatastatus(super.getOrgi(request) , user.getExtid() , false) ;
    			Extention extention = extentionRes.findByIdAndOrgi(user.getExtid(), super.getOrgi(request)) ;
    			if(extention!=null && userList.size() == 0) {
    				extention.setUserid(user.getId());
    				extention.setUsername(user.getUsername());
    				extention.setUname(user.getUname());
    				extentionRes.save(extention) ;
    				user.setExtno(extention.getExtention());
    			}else {
        			msg = "ext_exist" ;
        			user.setHostid(null);
        			user.setExtid(null);
        			user.setExtno(null);
        		}
    		}
    		userRepository.save(user) ;
    		OnlineUserUtils.clean(super.getOrgi(request));
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html?msg="+msg));
    }
    
    private String validUser(User user) {
    	String msg = "";
    	
    	List<User> userList = userRepository.findByDatastatusAndUsername(false, user.getUsername());
    	if(!StringUtils.isBlank(user.getUsername())){
    		if(userList != null && userList.size() > 0){
    			msg = "username_exist";
        		return msg;
    		}
    	}
    	
    	if(!StringUtils.isBlank(user.getEmail())){
    		userList = userRepository.findByDatastatusAndEmail(false, user.getEmail());
    		if(userList != null && userList.size() > 0){
				msg = "email_exist";
				return msg;
			}
		}
    	
    	if(!StringUtils.isBlank(user.getMobile())){
    		userList = userRepository.findByDatastatusAndMobile(false, user.getMobile()) ;
    		if(userList != null && userList.size() > 0){
				msg = "mobile_exist";
				return msg;
			}
		}
    	
    	return msg;
    }
    
    @RequestMapping("/edit")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView edit(ModelMap map ,HttpServletRequest request , @Valid String id, @Valid String p) {
    	ModelAndView view = request(super.createRequestPageTempletResponse("/admin/user/edit")) ;
    	User userData = userRepository.findByIdAndOrgi(id, super.getOrgiByTenantshare(request));
    	view.addObject("userData", userData) ;
    	if(UKDataContext.model.get("callcenter") != null) {
			List<PbxHost> pbxHostList = new ArrayList<>();
			SystemConfig systemConfig = UKTools.getSystemConfig();
			//多租户 要查租户和语音服务器的关联表
			if(systemConfig!=null&&systemConfig.isEnabletneant()) {

				List<String> pbxHostIds = new ArrayList<>();
				List<PbxHostOrgiRela> pbxHostOrgiRelaList = pbxHostOrgiRelaRepository.findByOrgi(super.getOrgi(request)) ;

				if(!pbxHostOrgiRelaList.isEmpty()) {
					for(PbxHostOrgiRela rel:pbxHostOrgiRelaList) {
						pbxHostIds.add(rel.getPbxhostid());
					}
				}
				if(pbxHostIds.size() > 0){
					pbxHostList = pbxHostRes.findByIdIn(pbxHostIds);
				}
			}else{
				pbxHostList = pbxHostRes.findByOrgi(super.getOrgi(request)) ;
			}
    		map.addAttribute("pbxHostList",pbxHostList);
    		if(pbxHostList!=null && !pbxHostList.isEmpty()) {
    			PbxHost pbxHost = pbxHostList.get(0) ;
    			map.addAttribute("pbxHost",pbxHost);
    			
    			if(userData != null && !org.apache.commons.lang3.StringUtils.isBlank(userData.getHostid())){
    				map.addAttribute("extentionList",extentionRes.findByHostidAndExtypeAndOrgi(userData.getHostid() , UKDataContext.ExtentionType.LINE.toString(), super.getOrgi(request)));
    			}
    			
    		}
    		
    	}
    	map.addAttribute("p", p);
        return view;
    }
    
    @RequestMapping("/update")
    @Menu(type = "admin" , subtype = "user" , admin = true)
    public ModelAndView update(HttpServletRequest request ,@Valid User user, @Valid String p) {
    	User tempUser = userRepository.findByIdAndOrgi(user.getId() , super.getOrgi(request)) ;
    	String msg = null ;
    	if(tempUser != null && !StringUtils.isBlank(user.getUsername())){
    		msg = validUserUpdate(user,tempUser);
    		if(!StringUtils.isBlank(msg)){
    			return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html?msg="+msg)); 
    		}
    		tempUser.setUname(user.getUname());
    		tempUser.setUsername(user.getUsername());
    		tempUser.setEmail(user.getEmail());
    		tempUser.setMobile(user.getMobile());
    		
    		tempUser.setMaxuser(user.getMaxuser());
    		
    		if(!StringUtils.isBlank(tempUser.getExtid())) {
				Extention tempExtention = extentionRes.findByIdAndOrgi(tempUser.getExtid(), super.getOrgi(request)) ;
				if(tempExtention!=null) {
					tempExtention.setUserid(null);
					tempExtention.setUsername(null);
					tempExtention.setUname(null);
					extentionRes.save(tempExtention) ;
				}
			}
    		
    		if(user.isBindext()){
    			
    			if(!StringUtils.isBlank(user.getExtid())) {
    				List<User> userList = userRepository.findByOrgiAndExtidAndDatastatus(super.getOrgi(request) , user.getExtid() , false) ;
    				Extention extention = extentionRes.findByIdAndOrgi(user.getExtid(), super.getOrgi(request)) ;
    				if(extention!=null && (userList.size() == 0 || userList.get(0).getId().equals(tempUser.getId()))) {
    					
    					if(!StringUtils.isBlank(tempUser.getExtid())) {
        					Extention tempExtention = extentionRes.findByIdAndOrgi(tempUser.getExtid(), super.getOrgi(request)) ;
        					if(tempExtention!=null) {
        						tempExtention.setUserid(null);
        						tempExtention.setUsername(null);
        						tempExtention.setUname(null);
        						extentionRes.save(tempExtention) ;
        					}
        				}
    					
    					tempUser.setExtno(extention.getExtention());
    					extention.setUserid(tempUser.getId());
    					extention.setUsername(tempUser.getUsername());
    					extention.setUname(tempUser.getUname());
    					tempUser.setHostid(user.getHostid());
    					tempUser.setExtid(user.getExtid());
    					extentionRes.save(extention) ;
    					
    					
    				}else {
    					msg = "ext_exist" ;
    				}
    			}else{
    				if(!StringUtils.isBlank(tempUser.getExtid())) {
    					Extention tempExtention = extentionRes.findByIdAndOrgi(tempUser.getExtid(), super.getOrgi(request)) ;
    					if(tempExtention!=null) {
    						tempExtention.setUserid(null);
    						tempExtention.setUsername(null);
    						tempExtention.setUname(null);
    						extentionRes.save(tempExtention) ;
    					}
    				}
    				tempUser.setHostid(user.getHostid());
    				tempUser.setExtid(null);
    				tempUser.setExtno(null);
    			}
    		}else{
    			if(!StringUtils.isBlank(tempUser.getExtid())) {
    				Extention tempExtention = extentionRes.findByIdAndOrgi(tempUser.getExtid(), super.getOrgi(request)) ;
    				if(tempExtention!=null) {
    					tempExtention.setUserid(null);
    					tempExtention.setUsername(null);
    					tempExtention.setUname(null);
    					extentionRes.save(tempExtention) ;
    				}
    			}
				tempUser.setHostid(null);
				tempUser.setExtid(null);
				tempUser.setExtno(null);
    		}
    		tempUser.setBindext(user.isBindext());
    		
    		
    		//切换成非坐席 判断是否坐席 以及 是否有对话
    		if(!user.isAgent()) {
    			AgentStatus agentStatus = (AgentStatus)CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request));
    	    	if(!(agentStatus==null && ServiceQuene.getAgentUsers(user.getId(), super.getOrgi(request))==0)) {
    	    		return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html?msg=t1")); 
    	    	}
    		}
    		tempUser.setAgent(user.isAgent());
    		
    		tempUser.setOrgi(super.getOrgiByTenantshare(request));
    		
    		if(!StringUtils.isBlank(super.getUser(request).getOrgid())) {
    			tempUser.setOrgid(super.getUser(request).getOrgid());
    		}else {
    			tempUser.setOrgid(UKDataContext.SYSTEM_ORGI);
    		}
    		
    		tempUser.setCallcenter(user.isCallcenter());
    		if(!StringUtils.isBlank(user.getPassword())){
    			tempUser.setPassword(UKTools.md5(user.getPassword()));
    		}
    		//是否是第二租户，除超级管理员所在租户下的其他租户
    		if(!tempUser.isSuperuser()  && super.getUser(request).isSuperuser()) {
    			if(request.getParameter("admin")!=null){
    				tempUser.setUsertype("0");
    			}else{
    				tempUser.setUsertype(null);
    			}
    		}
    		if(tempUser.getCreatetime() == null){
    			tempUser.setCreatetime(new Date());
    		}
    		tempUser.setUpdatetime(new Date());
    		userRepository.save(tempUser) ;
    		OnlineUserUtils.clean(super.getOrgi(request));
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html"+(msg!=null?"?msg="+msg:"")+"&p="+p));
    }
    
    private String validUserUpdate(User user,User oldUser) {
    	String msg = "";
    	
    	List<User> userList = userRepository.findByDatastatusAndUsername(false, user.getUsername());
    	
    	if(!StringUtils.isBlank(user.getUsername())){
    		
    		if(userList != null){
    			if(userList.size() > 0 && userList.size() == 1){
    				if(!userList.get(0).getUsername().equals(user.getUsername())){
    					msg = "username_exist";
    		    		return msg;
    				}
    			}else if(userList.size() > 0 && userList.size() > 1){
    				msg = "username_exist";
		    		return msg;
    			}
    		}
    		
    	}
    	
    	if(!StringUtils.isBlank(user.getEmail())){
    		userList = userRepository.findByDatastatusAndEmail(false, user.getEmail());
    		if(userList != null){
    			if(userList.size() > 0 && userList.size() == 1){
    				if(!userList.get(0).getEmail().equals(user.getEmail())){
    					msg = "email_exist";
    		    		return msg;
    				}
    			}else if(userList.size() > 0 && userList.size() > 1){
    				msg = "email_exist";
		    		return msg;
    			}
    		}
    		
    	}
    	
    	if(!StringUtils.isBlank(user.getMobile())){
    		userList = userRepository.findByDatastatusAndMobile(false, user.getMobile()) ;
    		if(userList != null){
    			if(userList.size() > 0 && userList.size() == 1){
    				if(!userList.get(0).getMobile().equals(user.getMobile())){
    					msg = "mobile_exist";
    					return msg;
    				}
    			}else if(userList.size() > 0 && userList.size() > 1){
    				msg = "mobile_exist";
    				return msg;
    			}
    		}
    		
    	}
    	
    	
    	return msg;
    }
    
    
    @RequestMapping("/delete")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView delete(HttpServletRequest request ,@Valid User user) {
    	String msg = "admin_user_delete" ;
    	if(user!=null){
	    	List<UserRole> userRole = userRoleRes.findByOrgiAndUser(super.getOrgiByTenantshare(request), user) ;
	    	userRoleRes.delete(userRole);	//删除用户的时候，同时删除用户对应的
	    	user = userRepository.findByIdAndOrgi(user.getId(),super.getOrgi(request)) ;
	    	user.setDatastatus(true);
	    	userRepository.save(user) ;
	    	
	    	if(!StringUtils.isBlank(user.getExtid())) {
				Extention tempExtention = extentionRes.findByIdAndOrgi(user.getExtid(), super.getOrgi(request)) ;
				if(tempExtention!=null) {
					tempExtention.setUserid(null);
					tempExtention.setUsername(null);
					tempExtention.setUname(null);
					extentionRes.save(tempExtention) ;
				}
			}
	    	
	    	OnlineUserUtils.clean(super.getOrgi(request));
    	}else{
    		msg = "admin_user_not_exist" ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html?msg="+msg));
    }
    
    @RequestMapping("/imp")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView imp(ModelMap map , HttpServletRequest request) {
        return request(super.createRequestPageTempletResponse("/admin/user/imp"));
    }
    
    @RequestMapping("/impsave")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView impsave(ModelMap map , HttpServletRequest request , @RequestParam(value = "cusfile", required = false) MultipartFile cusfile,@Valid String ckind,@Valid String itemid) throws IOException {
    	DSDataEvent event = new DSDataEvent();
    	String fileName = "user/"+UKTools.getUUID()+cusfile.getOriginalFilename().substring(cusfile.getOriginalFilename().lastIndexOf(".")) ;
    	File excelFile = new File(path , fileName) ;
    	if(!excelFile.getParentFile().exists()){
    		excelFile.getParentFile().mkdirs() ;
    	}
    	MetadataTable table = metadataRes.findByTablenameIgnoreCase("uk_user") ;
    	if(table!=null){
	    	FileUtils.writeByteArrayToFile(new File(path , fileName), cusfile.getBytes());
	    	event.setDSData(new DSData(table,excelFile , cusfile.getContentType(), super.getUser(request)));
	    	event.getDSData().setClazz(User.class);
	    	event.getDSData().setProcess(new UserProcess(userRepository));
	    	event.setOrgi(super.getOrgi(request));
	    	
	    	event.getValues().put("orgi", super.getOrgi(request)) ;
	    	event.getValues().put("orgid", super.getOrgi(request)) ;
	    	event.getValues().put("creater", super.getUser(request).getId()) ;
	    	event.getValues().put("createtime", new Date());
	    	reporterRes.save(event.getDSData().getReport()) ;
	    	new ExcelImportProecess(event).process() ;		//启动导入任务
    	}
    	
    	return request(super.createRequestPageTempletResponse("redirect:/admin/user/index.html"));
    }
    
    @RequestMapping("/extno")
    @Menu(type = "admin" , subtype = "user")
    public ModelAndView add(ModelMap map , HttpServletRequest request ,@Valid String hostid) {
    	if(UKDataContext.model.get("callcenter") != null) {
    		map.addAttribute("extentionList",extentionRes.findByHostidAndExtypeAndOrgi(hostid , UKDataContext.ExtentionType.LINE.toString(), super.getOrgi(request)));
    	}
        return request(super.createRequestPageTempletResponse("/admin/user/extno"));
    }
}